package collect;

import java.util.Map;

import com.google.common.collect.ForwardingMap;
import com.google.common.collect.ImmutableMap;

/**
 * Provides an {@link ImmutableMap} with easy syntax for creating new, immutable maps with an extra entry(-ies).
 * @author Carl A. Pearson
 *
 * @param <K>
 * @param <V>
 */
public class AppendableMap<K,V> extends ForwardingMap<K,V> {

	public AppendableMap(Map<K, V> source) {
		delegate = ImmutableMap.copyOf(source);
	}

	public static <K,V> AppendableMap<K,V> make(Map<K,V> source) {
		return new AppendableMap<K,V>(source);
	}
	
	private final ImmutableMap<K,V> delegate;
	
	@Override
	protected Map<K, V> delegate() { return delegate; }
	
	public AppendableMap<K,V> append(K key, V value) {
		if (containsKey(key)) throw new IllegalArgumentException();
		return make( ImmutableMap.<K,V>builder().putAll(delegate).put(key, value).build() );
	}
	
	public AppendableMap<K,V> append(Iterable<Entry<K,V>> entries) {
		ImmutableMap.Builder<K, V> builder = ImmutableMap.builder();
		for (Entry<K,V> entry : entries) {
			if (containsKey(entry.getKey())) throw new IllegalArgumentException();
			builder.put(entry.getKey(), entry.getValue());
		}
		return make (builder.putAll(delegate).build());
	}
	
	public AppendableMap<K,V> append(V value, K aKey, K ...keys) {
		if (containsKey(aKey)) throw new IllegalArgumentException();
		ImmutableMap.Builder<K, V> builder = ImmutableMap.<K,V>builder().put(aKey, value);
		for (K key : keys) {
			if (containsKey(key)) throw new IllegalArgumentException();
			builder.put(key, value);
		}
		return make (builder.putAll(delegate).build());

	}

}
